<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Matt Miller">
<meta name="GENERATOR" content="Mozilla/4.75 [en] (WinNT; U) [Netscape]"><title>RBNB DataTurbine Developer Guide</title>

</head>
<body>
<center>
<h1>
<hr width="100%"></h1>
</center>
<center>

<br><h1> RBNB DataTurbine</h1>
</center>
<center>
<h1> Software Developer Guide</h1>
</center>
<center>
<h1> V3.0</h1>
</center>
<center>
<h2> February, 2008</h2>
</center>
<hr width="100%">
<h1> Table of Contents</h1>
<blockquote><b><a href="#1%20Introduction">1
Introduction</a></b>
<blockquote><b><a href="#1.1%20Purpose">1.1
Purpose</a></b> <br>
<b><a href="#1.2%20Object%20Overview">1.2 Object
Overview</a></b> <br>
<b><a href="#1.3%20Programming%20Environments">1.3
Programming Environments</a></b></blockquote>
<b><a href="#2%20ChannelMap">2 ChannelMaps</a></b>
<blockquote><b><a href="#2.1%20Channel%20Names">2.1
Channel Names</a></b> <br>
<b><a href="#2.2%20Channel%20DataTypes">2.2
Channel DataTypes</a></b> <br>
<b><a href="#2.3%20Channel%20TimeStamps">2.3
Channel TimeStamps</a></b> <br>
<a href="#ChannelMap_Registration" style="font-weight: bold;">2.4 ChannelMap
Registration</a><br>
<b><a href="#2.4%20ChannelMap%20Methods">2.5
ChannelMap Methods</a><br>
<a href="#2.6_Channel_Trees">2.6 Channel Trees</a></b></blockquote>
<b><a href="#3%20Clients">3 Clients</a></b>
<blockquote><b><a href="#3.1%20Base%20Client">3.1
Base Client</a></b> <br>
<a href="#3.2_Source_Client"><b>3.2 Source
Client</b></a> <br>
<b><a href="#3.3%20Sink%20Client">3.3 Sink Client</a></b>
<br>
<b><a href="#3.4%20PlugIn%20Client">3.4 PlugIn
Client</a><br>
</b></blockquote>
<a style="font-weight: bold;" href="#4_Routing_and_Mirrors">4
Routing and Mirrors</a><br>
<br>
<div style="margin-left: 40px;"><a style="font-weight: bold;" href="#4.1_Mirrors_">4.1
Mirrors</a><br>
</div>
<div style="margin-left: 40px;"><a style="font-weight: bold;" href="#4.2_Routing">4.2
Routing</a><br>
</div>
<br>
<a style="font-weight: bold;" href="#5_Web_Turbine">5
WebTurbine</a><br>
<div style="margin-left: 40px;"><a style="font-weight: bold;" href="#5.1_WebTurbine_Introduction">5.1
WebTurbine Introduction</a><br style="font-weight: bold;">
<a style="font-weight: bold;" href="#5.2_Web_URL_Access">5.2
Web URL Access</a><br style="font-weight: bold;">
<a style="font-weight: bold;" href="#5.3_File_System_Access">5.3
File System Access</a><br style="font-weight: bold;">
<a style="font-weight: bold;" href="#5.4_Programmer_Interface">5.4 Programmer Interface</a><br>
</div>
<br>
</blockquote>
<hr width="100%">
<h1> <a name="1 Introduction"></a>1&nbsp;&nbsp;&nbsp;
Introduction</h1>
This
is an update to the older V2 Developer Guide. &nbsp;It trims some
deprecated and obsolete material, updates and expands where things have
changed (e.g. <span style="font-style: italic;">ChannelTree</span>,
<span style="font-style: italic;">PlugInTemplate</span>),
and adds new sections for the <span style="font-style: italic;">WebTurbine</span>
and <span style="font-style: italic;">Routing</span>
capabilities.<h2> <a name="1.1 Purpose"></a>1.
1&nbsp;&nbsp; Purpose</h2>
This manual provides an overview of the RBNB&nbsp;Application
Programming Interface, for historical reasons known as the "Simple API"
(SAPI). The SAPI is designed to provide maximum capability with minimum
complexity. This document is not a complete reference for
all available SAPI methods. &nbsp;For a rigorous reference
document, see the associated Javadoc and
Doxygen&nbsp;documentation.
<p>The SAPI is implemented as a set of methods on top of the RBNB
Java "RMap" or "Full" API, which is what the RBNB server itself is
written to.&nbsp; The full RMap API
is not supported for open access, but the SAPI is meant to be a highly
functional, self contained interface to the RBNB. </p>
<h2> <a name="1.2 Object Overview"></a>1.2&nbsp;&nbsp;&nbsp;
Object Overview</h2>
There are two main types of objects in the Simple API:
<blockquote> <li> <tt>ChannelMap</tt></li>
<li> <tt>Client</tt></li>
</blockquote>
The <i>ChannelMap</i> object organizes data.&nbsp;
ChannelMaps are used by RBNB clients to send, request, and retrieve
data from an RBNB server.
<p>A <i>Client</i> object can be one of the
following sub-classes: </p>
<blockquote> <li> <tt>Source</tt></li>
<li> <tt>Sink</tt></li>
<li> <tt>PlugIn</tt></li>
</blockquote>
An RBNB software developer writes RBNB "clients".&nbsp; Clients
communicate with an RBNB server to send and retrieve data via <span style="font-style: italic;">ChannelMaps</span>. A <i>Source</i>
client sends data to the RBNB Server.&nbsp; A <i>Sink</i>
fetches data from an RBNB Server.&nbsp; A <i>PlugIn</i>
receives requests (from the server on behalf of a <i>Sink</i>)
and responds with data (thus acting like both a <i>Sink</i>
and <i>Source</i>). <br>
<br>
The
following figure illustrates how Source and Sink clients connect to an
RBNB server. &nbsp;Overall geometric scalability (MxN) is achieved
through a combination of linear (1xM and Nx1) internal objects.<br>
<br>
<div style="text-align: center;"><img style="width: 370px; height: 243px;" src="RBNB%20Structure.jpg" alt="RBNB Structure"></div>
<div style="text-align: center;"><span style="font-weight: bold;">RBNB Achieves Geometric
Scalability with Linear Internal Structures</span><br>
</div>
<h3> Channel Map</h3>
All RBNB data is organized in "channel maps".&nbsp;RBNB clients
manipulate channel maps as a means to make requests (sinks) and
submit data (sources). A channel map consists of a collection
of&nbsp;channel objects, each with three main components:<br><br><table style="width: 60%; height: 1px; text-align: left; margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td><span style="font-family: monospace;">Name</span></td><td style="text-align: left;">Text name e.g. "myChannel"</td></tr><tr><td><span style="font-family: monospace;">Data</span></td><td>Binary data of various types</td></tr><tr><td><span style="font-family: monospace;">TimeStamp</span></td><td>Monotonically increasing floating point number</td></tr></tbody></table><br>A source client builds a channel map consisting of one or more
named channels.&nbsp; For each channel it provides data of a
specified type and quantity.&nbsp; It also specifies a&nbsp;
timestamp for the channel map as a whole, or for the various pieces
(channels and data) separately.&nbsp; After being so
built, the channel map is sent from the source client to the RBNB
server.&nbsp;
This process can be repeated, adding new channels or new data to
existing
channels. 
<p>A sink client builds a channel map in order to request
data.&nbsp; Here, the channel map consists of named channels and
timestamps, which is sent to the RBNB server as a request.&nbsp;
The response to this request is another channel map, this time with the
data filled in for the various channels.</p>
<p>A "channel tree" is an optional channel map accessory that
provides a hiearchical read-only view of &nbsp;a channel map. </p>
<h3> Source Client</h3>
Source clients are "active", that is they initiate data transmittal to
the server.&nbsp; Each time a source sends some data to the server,
it is called a "frame".&nbsp; A source can send a sequence of
frames to the server.&nbsp; Each frame can consist of one or more
named "channels".&nbsp; Each channel can consist of one or more
data points per frame.
<p>Key to the idea of RBNB is that all data has monotonically
increasing time-stamps.&nbsp; Timestamps can be per frame, per
channel, and/or per data point.&nbsp; Timestamps can be explicit
(provided by the source), or implicit (automatically provided by the
client API or RBNB server). </p>
<h3> Sink Client</h3>
Sink clients are "active", that is they initiate data retrieval from
the server.&nbsp; Just as for a source, each time a sink gets
frames of data from a server.&nbsp; Each frame consists of one or
more named channels, with each channel consisting of one or more data
points.
<p>A sink requests data by both channel name(s) and
timestamp.&nbsp; The data
returned to a sink can consist of multiple or partial source frames,
depending
upon the requested time slice.&nbsp; There are three modes by which
a sink
can get data from a server: </p>
<blockquote> <li> Request</li>
<li> Subscribe</li>
<li> Monitor</li>
</blockquote>
Requests are for a particular time interval, for which there is a
single response for each such request.&nbsp; It is also possible to
make a single request that is automatically repeated over a specified
number of time intervals.
<p>Subscribe and Monitor modes are open-ended in that new data is
automatically sent (from the server to the sink client) as it becomes
available.&nbsp; Subscribe mode fetches all data, even if this
means falling behind real-time.&nbsp; Monitor mode skips data in
order to stay current. </p>
<h3> PlugIn Client</h3>
PlugIn clients are "passive sources", that is
they appear to other clients as RBNB sources, but wait for data
requests before sending data to in response to those requests. PlugIns
implement both sink and source connections. The server passes to the
PlugIn
any requests for PlugIn channels to the PlugIn sink
connection.&nbsp;
Upon receipt of a request, a PlugIn
acts as a source and sends its response to the server, which forwards
it to the requesting sink.
<p>A PlugIn optionally registers the specific channels it can
provide. Registered channels do not have any data in them, they are a
means of "advertising" available channels. With registered channels,
only requests for those specific channels will be forwarded by the
server to that PlugIn. Otherwise, any request
(e.g. "Plugin/anychan") is forwarded to the PlugIn, which can invent
channels on-the-fly. </p>
<p>Thus, a PlugIn can provide "services" that can involve
fetching and processing other RBNB data on the demand of third party
applications.&nbsp; PlugIns
can process data from other PlugIns, thus cascading sequences of
processing
steps. </p>
<h2> <a name="1.3 Programming Environments"></a>1.3&nbsp;
Programming Environments</h2>
Whereas
earlier versions of the RBNB flirted with supporting various
programming languages and environments, the latest version is focused
on Java as the primary programmer API-level interface. &nbsp;Other
environments remain supported via various higher-level
&nbsp;layers,
such as via HTTP using the WebTurbine interface. &nbsp;There is
also a
lurking MS dot-Net interface via J# in a Java-compatable mode.<br>
<h3> Java</h3>
The RBNB server and its API are themselves developed using 100% pure
Java.&nbsp; Thus, the core API and its documentation is Java based.
<h3> MATLAB&nbsp;</h3>
With Version 6 and later of Matlab, direct calls to Java are supported
from the command line mode of Matlab.&nbsp; Thus, Matlab uses the
native Java
RBNB API directly.&nbsp; Several simple utility M-files are
provided as examples.
<p>In order to access the RBNB API from Matlab, you must edit the
Matlab classpath.txt
file to include the rbnb.jar file.&nbsp;&nbsp;</p>
RBNB
also works via the Matlab-compatable COMSOL script environment.
&nbsp;To enable this, one must &nbsp;setup the COMSOL
"javaDeclare" and
MANIFEST.MF files.<br>
<hr width="100%">
<h1> <a name="2 ChannelMap"></a>2&nbsp;&nbsp;&nbsp;
ChannelMap</h1>
Clients manipulate data via a "ChannelMap" object. A ChannelMap is
comprised of one or more RBNB channels, each consisting of a name,
timestamp, and (optional)
data.
<p>Channels are individually identified and "staged" using the <a href="#ChannelMap.Add">ChannelMap.Add</a> method prior
to being transferred (<a href="#Sink.Fetch">Fetch</a>
or <a href="#Source.Flush">Flush</a>).
Behind the scenes, the SAPI incrementally builds up and maintains the
underlying "RMap" data structures. </p>
<h2> <a name="2.1 Channel Names"></a>2.1&nbsp;&nbsp;&nbsp;
Channel Names</h2>
Multi-tiered hierarchical channel structures can be created, requested,
and referenced through a simple directory-like naming
convention.&nbsp; A fully specified channel name consists of three
main parts:
<blockquote><tt>Server/Source/Channel</tt></blockquote>
Where:
<blockquote><tt>Server:&nbsp;&nbsp;&nbsp;
serverName assigned at Server startup (command line argument)</tt>
<br>
<tt>Source:&nbsp;&nbsp;&nbsp; clientName given by
Source via OpenRBNBConnection method</tt> <br>
<tt>Channel:&nbsp;&nbsp; channelName given by Source
via ChannelMap.Add method</tt></blockquote>
Data Sources define channels (<a href="#ChannelMap.Add">ChannelMap.Add</a>)
with the Server and Source parts implied. The channel name part may
itself be multi-tiered, such as:
<blockquote><tt>Chan0</tt> <br>
<tt>Test43/C0</tt> <br>
<tt>Test43/C1</tt> <br>
<tt>A/B/C</tt></blockquote>
Data Sinks request channels (<a href="#ChannelMap.Add">ChannelMap.Add</a>)
using either relative or absolute (full-path) names. For example:
<blockquote><tt>/Server/MySource/Test43/C2&nbsp;&nbsp;&nbsp;
# absolute path</tt> <br>
<tt>MySource/Test43/C2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
# relative path</tt></blockquote>
Absolute paths start with a slash, and include the top level (parent)
server all the way down to the channel name(s).&nbsp; Relative
paths do
not start with a slash, and begin with a Source name on the local
server.
<p>For Sinks, and when requesting a list of available Server
channels, wildcards can also be used, as in: </p>
<blockquote><tt>MySource/Test/...</tt> <br>
<tt>*/c0</tt> <br>
<tt>/Server/*/_Msg/...</tt></blockquote>
The following Table summarizes the wildcard syntax available to the <a href="#ChannelMap.Add">ChannelMap.Add</a> (Sink-only)
and <a href="DeveloperGuideV3.html#Sink.RequestRegistration">Sink.RequestRegistration</a>
methods. <br>
&nbsp;
<center>
<table border="1" width="89%">
<tbody>
<tr>
<td><b>Match String</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td><tt>"*"</tt></td>
<td>All objects (servers/sources/channels) at this level
(one deep)</td>
</tr>
<tr>
<td><tt>"..."</tt></td>
<td>All channels this level and down (recursive
depth).&nbsp; Must be last part of multi-tiered name.</td>
</tr>

</tbody><caption align="bottom">
<center><b>SAPI Channel Naming Wildcard Notation</b></center>
</caption>
</table>
</center>
<h2> <a name="2.2 Channel DataTypes"></a>2.2&nbsp;&nbsp;&nbsp;
Channel DataTypes</h2>
ChannelMap Data (<a href="#2.4.3%20Putting%20Data">PutData</a>)
can be specified as a particular primitive data type, per the following
table. <br>
&nbsp;
<center>
<table border="1" width="89%">
<tbody>
<tr>
<td><a name="DataType Codes"></a><b>DataType
Code</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td><tt>TYPE_FLOAT32</tt></td>
<td>Single precision (32 bit) floating point number</td>
</tr>
<tr>
<td><tt>TYPE_FLOAT64</tt></td>
<td>Double precision (64 bit) floating point number</td>
</tr>
<tr>
<td><tt>TYPE_INT8</tt></td>
<td>8-bit integer (byte)&nbsp;</td>
</tr>
<tr>
<td><tt>TYPE_INT16</tt></td>
<td>16-bit integer (short int)</td>
</tr>
<tr>
<td><tt>TYPE_INT32</tt></td>
<td>32-bit integer (int)</td>
</tr>
<tr>
<td><tt>TYPE_INT64</tt></td>
<td>64-bit integer (long)</td>
</tr>
<tr>
<td><tt>TYPE_STRING</tt></td>
<td>Variable length String (character array) object</td>
</tr>
<tr>
<td><tt>TYPE_UNKNOWN</tt></td>
<td>Unknown or unspecified (byte array)</td>
</tr>
<tr>
<td><tt>TYPE_BYTEARRAY</tt></td>
<td>Array of arrays of bytes (byte[][])</td>
</tr>
<tr>
<td><tt>TYPE_USER</tt></td>
<td>User metadata</td>
</tr>
</tbody><caption align="bottom">
<center><b>SAPI DataType Codes</b></center>
</caption>
</table>
</center>
<p>When specifying a primitive DataType with a word length
greater than 8 bits (1 byte), the word order (MSB,LSB) is automatically
set to match that of the local native CPU upon which the Source
application runs. </p>
<h2> <a name="2.3 Channel TimeStamps"></a>2.3&nbsp;&nbsp;&nbsp;
Channel TimeStamps</h2>
A Source sets the timestamp for subsequent data transmittal using
either a manual (<a href="#ChannelMap.PutTime">PutTime</a>)
or automatic (<a href="#ChannelMap.PutTimeAuto">PutTimeAuto</a>)
method. &nbsp;A timestamp is a monotonically-increasing double-precision number that defines
"when" the data occurred. &nbsp;&nbsp;The
simplest form of timestamp would be to simply count by whole-numbers,
e.g. t=0,1,2,3,...<br>
<br>
Default (automatic) timestamp are&nbsp;floating-point number of
seconds since 1970, re native Java time or Unix time. &nbsp;For
compatability with other applications, it is suggested (but not
required) that you adhere to this time-stamping convention.
<p>Each manual timestamp applies to the data specified by one or
more subsequent calls to <a href="#ChannelMap.PutData">PutData</a>,
until a time-setting method is called again.&nbsp; Thus, you can
choose to timestamp data point by point, channel by channel, or frame
by frame depending on how you interleave your calls to PutTime and
PutData. </p>
<p>Automatic time stamps are updated once upon each data <a href="#Source.Flush">Flush</a>.&nbsp; Thus,
automatic timestamps are always frame by frame. </p>
<p>Note that RBNB timestamps must monotonically increase.&nbsp; Thus,
if you are manually providing timestamps, be sure to never decrease the start time call-to-call.<br>
</p>
<h2><a name="ChannelMap_Registration"></a>2.4
&nbsp; &nbsp;ChannelMap Registration</h2>
When a Source puts ChannelMaps to a server, the channels are
automatically registered. &nbsp;See <a href="#Sink.RequestRegistration">Sink.RequestRegistration</a>
for how to get the ChannelMap from which a list of channel strings may
be obtained. &nbsp;<br>
<br>
A Source or PlugIn can also specifically register its channels, and in
so doing add "metadata" (descriptive information) about the
channels.&nbsp; That
is, the datablock in the registration ChannelMap is descriptive
meta-data about the corresponding Source channel. &nbsp;Since the
registration information is not part of the ring-buffer, this meta-data
is static (i.e. does not
change with time, nor does it "drop off" the ring buffer). <br>
<h2><a name="2.4 ChannelMap Methods"></a>2.5
&nbsp;&nbsp; ChannelMap Methods</h2>
<h3> <a name="2.4.1 Construction"></a>2.5.1&nbsp;&nbsp;&nbsp;
Construction</h3>
The following ChannelMap methods build, edit and access the list of
channels.
<h4> <a name="ChannelMap.Add"></a><tt>int
Add(String channelName)</tt></h4>
Each call to ChannelMap.Add builds up the list of channels to be either
sent or fetched by the Source or Sink, respectively.&nbsp;
ChannelMap.Add returns an index that increments with the number of
channels added.&nbsp; For Sources, this index can be used as the
reference index for use in the PutData method.&nbsp; It is safe to
presume this index starts at 0 and increments by 1 each call to <span style="font-family: monospace;">Add</span> with a new or cleared ChannelMap.<br><br>For Sinks, it
is possible to get more or less channels than you specify (e.g. using
wildcards), so you must inquire (with GetName or GetIndex) which
channels have been <a href="#Sink.Fetch">Fetched</a>.
<h4> <a name="ChannelMap.Clear"></a><tt>void
Clear()</tt></h4>
This method clears out the channel map built by the <a href="#ChannelMap.Add">ChannelMap.Add</a> method, and
frees associated memory.&nbsp; Use it when you want to build a new
channel map from a "clean slate".
<h3> <a name="2.4.3 Putting Data"></a>2.5.2&nbsp;&nbsp;&nbsp;
Putting Data and Timestamps</h3>
The following methods put data in a ChannelMap.&nbsp; These are
generally used by Data Sources (and PlugIns).
<p>Note that putting data into a ChannelMap does not send the
data to an RBNB
server, it builds a local ChannelMap.&nbsp; After building the
ChannelMap, it is sent from the client to the RBNB server via the <a href="#Source.Flush">Source.Flush</a> method. </p>
<h4> <a name="ChannelMap.PutData"></a><tt>void
PutData(int chanIndex, byte[] rawData, int typeID)</tt></h4>
The generic PutData method sets the data to be sent as a byte-array
plus an associated <tt>typeID</tt>.&nbsp; The <tt>typeID</tt>
is one of the <a href="#DataType%20Codes">DataTypeCodes</a>.&nbsp;
Use the channel index
from the associated <a href="#AddChannel">ChannelMap.Add</a>
method, or use
the <a href="#ChannelMap.Index">GetIndex</a>
method.
<p><b><i>Note:</i></b>&nbsp; Mixing
different DataTypes in a single channel is not supported, and may cause
difficulties for Sink applications that try
to extract mixed-type data. </p>
<h4> <a name="ChannelMap.PutDataAsXXX"></a><tt>void
PutDataAsXXX(int chanIndex, XXX[] data)</tt></h4>
The family of PutDataAsXXX methods specifies the primitive type of the
supplied data array, where XXX corresponds to one of the <a href="#DataType%20Codes">DataType Codes</a>.&nbsp;
For example, PutDataAsFloat32 lets you directly send a floating point
data array with no need to first
convert it to a byte array. (Overloaded methods are not used to enhance
portability of the SAPI).
<p><b><i>Note</i></b>:&nbsp;
PutDataAsString puts a <i>single </i>String object,
which is considered to be an indivisible data word. </p>
<h4> <a name="ChannelMap.PutTime"></a><tt>void
PutTime(int chanIndex, double start, double duration)</tt></h4>
<h4> <a name="ChannelMap.PutTimes"></a><tt>void
PutTimes(double[] times)</tt></h4>
<h4> <a name="ChannelMap.PutTimeAuto"></a><tt>void
PutTimeAuto(String timeMode)</tt></h4>
<a name="ChannelMap.PutTimeRef"></a><b><tt>void
PutTimeRef(ChannelMap
sourceMap, int channelIndex)</tt></b>
<p>These methods establish the time-stamping method for the
ChannelMap.&nbsp; All PutData calls following a PutTime call will
be timestamped accordingly.&nbsp; For example, you can call PutTime
once for the whole ChannelMap, in which case all data for all channels
share a common timestamp.&nbsp; Or you can PutTime separately
before every PutData call, giving unique timestamps to every data point
for every channel. </p>
<h3> <a name="2.4.2 Getting Data"></a>2.5.3&nbsp;&nbsp;&nbsp;
Getting Data and Timestamps</h3>
The following methods access the data in a ChannelMap. These are
generally used by Data Sinks (and PlugIns).
<p>Note that getting data from a ChannelMap does not fetch it
from the RBNB server, it extracts it from a local ChannelMap.&nbsp;
Prior to getting data, the ChannelMap is sent from the RBNB server to
the client via the <a href="#Sink.Fetch">Sink.Fetch</a>
method. </p>
<h4> <tt>byte[] GetData(int chanIndex)</tt></h4>
This generic extract data method gets data as a byte-array from the
ChannelMap.
<h4> <a name="ChannelMap.GetDataAsXXX"></a><tt>XXX[]
GetDataAsXXX(int chanIndex)</tt></h4>
The family of ChannelAsXXX methods specifies the primitive data type of
the returned data array, where XXX corresponds to one of the <a href="#DataType%20Codes">DataType Codes</a>.&nbsp;
For example, GetDataAsFloat32 lets you retrieve a floating point data
array with no need to convert it
from a byte array.&nbsp; If the fetched data does not match the
type, an
exception will be thrown.&nbsp; You can check the type using the
ChannelType
method.
<p><b><i>Note</i></b>:&nbsp;
GetDataAsString gets an <i>array</i> of <tt>String</tt>
objects, where each <tt>String</tt> is considered to be an
indivisible, individually
time-stamped, variable-length data word. </p>
<h4> <a name="ChannelMap.GetTimes"></a><tt>double[]
GetTimes(chanIndex)</tt></h4>
This method returns an array of double precision RBNB time values for
the specified channel index. There will be one time point per data
point.If
necessary, the point times will be linearly interpolated from the
underlying start time and duration of the corresponding data
array.&nbsp; See <a href="#ChannelMap.PutTime">PutTime</a>.
<h3> <a name="2.4.4 ChannelMap Utilities"></a>2.5.4&nbsp;&nbsp;
DataType
Info</h3>
These methods provide information about the datatype of a channel.
<h4> <a name="ChannelMap.GetType"></a><tt>int
GetType(int chanIndex)</tt></h4>
This method returns a <a href="#DataType%20Codes">DataType
Code</a> for the primitive data type of the fetched data for a
given channel.&nbsp; It can be used to determine which of the
GetDataAsXXX methods to call.
<h4> <a name="ChannelMap.TypeID"></a><tt>int
TypeID(String type)</tt></h4>
<h4> <a name="ChannelMap.TypeName"></a><tt>String
TypeName(int typeID)</tt></h4>
These methods convert the datatype string to numerical constant, and
vice versa. <br>
<br>
There are several methods to let you inspect and get the names of the
channels in a ChannelMap object.&nbsp; The methods are:<br>
<h4> <a name="ChannelMap.Name"></a><tt>String
GetName(int index)</tt></h4><h4><tt><tt><a name="GetChannelList"></a>String[]
GetChannelList()</tt></tt>&nbsp;</h4>These
utility methods provide&nbsp;means to get the channel name(s) for a
given ChannelMap. For Sinks, you can use this method to discover which
channels were successfully <a href="#Sink.Fetch">Fetched</a>.<br>
<h4> <a name="ChannelMap.Index"></a><tt>int
GetIndex(String channelName)</tt></h4>
This utility method provides a means to get the channel <tt>index</tt>
given the <tt>channelName</tt>.&nbsp; For Sources, the
return value of <a href="#ChannelMap.Add">ChannelMap.Add</a>
is a reliable channel index.&nbsp; For Sinks, you may need to use
this method to determine the reference index of <a href="#Sink.Fetch">Fetched</a>
channels.<br>
<h2> <a name="2.6_Channel_Trees"></a>2.6
&nbsp;&nbsp; Channel Trees</h2>
The ChannelTree class provides per-node&nbsp;channel hierarchy
construction and identification methods. &nbsp;It replaces the
deprecated ChannelList and NodeList methods. &nbsp;It is a
client-side
layer that provides read-only access to the underlying ChannelMap
object. &nbsp;<br>
<br>
The ChannelTree has <span style="font-style: italic;">Controller</span>,
<span style="font-style: italic;">Server</span>,&nbsp;<span style="font-style: italic;">Source</span>, <span style="font-style: italic;">Plugin</span>, <span style="font-style: italic;">Sink</span>, <span style="font-style: italic;">Folder</span>,&nbsp;<span style="font-style: italic;">Channel</span>, and <span style="font-style: italic;">Empty</span> nodes.
&nbsp;These correspond to logical filesystem-like entities rather
than a direct correspondence to the ChannelMap object.
<h4> <a name="ChannelTree.createFromChannelMap"></a><tt>ChannelTree
createFromChannelMap(ChannelMap cmap)</tt></h4>
Creates a new read-only view of the provided channel map.<br>
<span style="font-style: italic;"></span><br>
See the SAPI&nbsp;<span style="font-style: italic;">Javadoc</span>
for additional ChannelTree methods.<br>
<br>
<hr width="100%">
<h1> <a name="3 Clients"></a>3&nbsp;&nbsp;&nbsp;
Clients</h1>
Clients manipulate <i>ChannelMaps</i> to send and receive
data from an RBNB server.
<h2> <a name="3.1 Base Client"></a>3.1&nbsp;&nbsp;&nbsp;
Base Client</h2>
The <i>Client</i> class is the base class of all simple
clients (<i>Source</i>, <i>Sink</i>, <i>PlugIn</i>)
to RBNB servers.&nbsp; The base <i>Client</i> class
encapsulates functionality common to all clients.
<h3> <a name="3.1.1 Client Connections"></a>3.1.1&nbsp;&nbsp;&nbsp;
Client Connections</h3>
Clients have methods to open and close connections between the client
application and an RBNB server.
<h4> <a name="OpenRBNBConnection"></a><tt>void
OpenRBNBConnection(String
serverAddress, String clientName, String userName, String password)</tt></h4>
To open a connection identify the server (<tt>serverAddress</tt>),
and identify the client (<tt>clientName</tt>).&nbsp;
The <tt>clientName</tt> is
used for display in applications such as <i>rbnbAdmin</i>,
and provides a
handle for other applications to administer and access data from this
client.
<p>Clients optionally provide a <tt>userName</tt>
and <tt>password</tt> as part of the connection
process.&nbsp; If these are defaulted to NULL, there will be no
user name by which you can be granted access to restricted data. </p>
<p><b><i>Note</i></b>:&nbsp;&nbsp;<tt>userName</tt>
and <tt>password</tt>
authorization has limited utility and is only implemented by some
clients. &nbsp;The subject of RBNB data access authorization is the
subject of other documents. </p>
<h4> <a name="CloseRBNBConnection"></a><tt>void
CloseRBNBConnection()</tt></h4>
Close the connection with the server, and free up associated resources.
&nbsp;The <span style="font-family: monospace;">related Source.Detach</span> method disconnects while leaving data intact.<br>
<h3> <a name="3.1.2 Server Object Lists"></a>3.1.2&nbsp;&nbsp;&nbsp;
Get
Server Info</h3>
&nbsp;It is possible to get a the name of the connected server, and
of yourself (the connected client).
<h4> <a name="Client.GetServerName"></a><tt>String[]
GetServerName()</tt></h4>
<h4> <a name="Client.GetClientName"></a><tt>String[]
GetClientName()</tt></h4>
These methods return the name of the local RBNB server, and the name of
the connected client application, respectively.
<h3> <a name="3.1.3 Ring Buffer Properties"></a>3.1.3&nbsp;&nbsp;&nbsp;
Ring Buffer Properties</h3>
<h4> <a name="Client.SetRingBuffer"></a><tt>SetRingBuffer
(int cacheSize, String archiveMode, int archiveSize)</tt></h4>
Clients can set the size of the RBNB server ring buffer associated with
its data.&nbsp; Normally, this only applies to Source
clients.&nbsp;&nbsp;
<p>The <tt>cacheSize</tt> and <tt>archiveSize</tt>
parameters specify the sizes of the RAM and disk ring buffers (in
frames), respectively.&nbsp; Each
call to "Flush" by a Source constitutes one "frame". </p>
<p>The <tt>archiveMode</tt> parameter has one of the
following values: </p>
<p><tt>&nbsp;&nbsp;&nbsp;
"none"&nbsp;&nbsp; - </tt>No archive is to be used
(default) <br>
<tt>&nbsp;&nbsp;&nbsp; "load"&nbsp;&nbsp; - </tt>Load
the archive that
matches this application <tt>clientName</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; "create" - </tt>Create
a new archive, delete an
existing one if one is present <br>
<tt>&nbsp;&nbsp;&nbsp; "append" - </tt>Add to
an existing archive, create a new one if necessary </p>
<hr width="100%">
<h2><a name="3.2_Source_Client"></a>&nbsp;3.2&nbsp;&nbsp;&nbsp;
Source Client</h2>
An RBNB data source sends data to and RBNB server. A data Source client
has the following tasks, which may be repeated as desired:
<blockquote> <li> Define a ChannelMap</li>
<li> Set TimeStamp(s)</li>
<li> Specify data for channel(s)</li>
<li> Flush data to RBNB server</li>
</blockquote>
<h3> <a name="3.2.1 Define Channel Map"></a>3.2.1&nbsp;&nbsp;&nbsp;
Define Channel Map</h3>
A Source channel map is defined by calls to the <a href="#ChannelMap.Add">ChannelMap.Add</a>
method.&nbsp; This associates
channel names with channel indices, which in turn are used for
efficient,
potentially repeated references in the <a href="#ChannelMap.PutData">ChannelMap.PutData</a>
method.
<h3> <a name="3.2.2 Time Stamps"></a>3.2.2&nbsp;&nbsp;&nbsp;
Time Stamps</h3>
ChannelMap timestamps are specified using the <a href="#ChannelMap.PutTime">ChannelMap.PutTime</a>
method(s).
<h3> <a name="3.2.3 Specify Channel Data"></a>3.2.3
Specify Channel Data</h3>
The <tt>PutData</tt> methods specify the channel data to
send at the next call to the <tt>Flush</tt>
method.&nbsp; These methods reference the channels by the index
returned by <a href="#ChannelMap.Add">ChannelMap.Add</a>.
They provide data either as a generic byte-array or as a particular
data type.
<p>PutData may be called multiple times per channel per Flush,
building up a many-point-per-channel data frame in a piecemeal manner
as may be convenient to the application.&nbsp; The SAPI has
internal logic which automatically consolidates and organizes data into
efficient channel map structures.&nbsp; It will always be more
effective to handle fewer, larger data buffers, however. </p>
<h3> <a name="3.2.4 Flush Data"></a>3.2.4
Flush Data</h3>
Once things are set up, send the data to the server.
<h4> <a name="Source.Flush"></a><tt>int
Source.Flush(ChannelMap cmap, boolean blockingIO)</tt></h4>
After staging information with the time and data setting methods (i.e. <a href="#ChannelMap.PutTime">PutTime</a> and <a href="#ChannelMap.PutData">PutData</a>), the specified
channel map is sent as a consolidated RMap with the Flush method.
<p>Each call to Flush involves round-trip network communication,
therefore staging larger data frames (with larger buffers and/or
multiple calls to PutData) prior to flushing them may provide a
significant performance advantage. Of course, you need to also consider
the associated impact on memory use and
latency when deciding how often to Flush your data. </p>
<p>If the <tt>blockingIO</tt> parameter is <tt>true</tt>,
it will block until the data is sent.&nbsp; If there is no data to
send, calling <tt>Flush(cmap,true)</tt> will synchronize
your application with the server.&nbsp;&nbsp; It returns the
number of channels sent. </p>
<p><b><i>Note</i></b>: Flushing the
channel map clears the data.&nbsp; Thus, only new data (via
PutData) since the previous call to Flush are sent each time. </p>
<h3> <a name="3.2.5 Example Source Code"></a>3.2.5
Source Example Code</h3>
The following code opens a connection to a local RBNB server and sends
a message string to it. &nbsp;The timestamp
defaults to time-of-day in lieu of using the PutTime method.<br>
&nbsp;
<center>
<table style="width: 95%;" border="1" cols="1">
<tbody>
<tr>
<td> <tt>// RBNB Developer Guide Simple Source
Example<br>
<br>
import com.rbnb.sapi.*;<br>
<br>
class simpleSource<br>
{<br>
&nbsp;&nbsp;&nbsp; public static void main(String[] arg)
throws Exception<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Source
mySource = new Source();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
ChannelMap cmap = new ChannelMap();<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
mySource.OpenRBNBConnection("localhost",
"mySource");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
cmap.Add("myChan");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
cmap.PutDataAsString(0, "Hello World!");<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
mySource.Flush(cmap, true);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
Thread.sleep(5000);&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; // sleep to
let data be viewed<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
mySource.CloseRBNBConnection();&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; //
data goes poof on close<br>
&nbsp;&nbsp;&nbsp; }<br>
}</tt>
</td>
</tr>
</tbody><caption align="bottom"><b>Simple
Source Example Code</b></caption>
</table>
</center>
<h2>
<hr width="100%"></h2>
The following code is a more complex example, showing how to
write sequential data frames for multiple channels in a loop with
simply-indexed timestamps. <br>
<br>
<center>
<table border="1" cols="1" width="95%">
<tbody>
<tr>
<td> <span style="font-family: monospace;">//
RBNB Developer Guide Looping Source Example</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">import
com.rbnb.sapi.*;</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">class
loopSource</span><br style="font-family: monospace;">
<span style="font-family: monospace;">{</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
public static void main(String[] arg) throws Exception</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
{</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; int nchan = 3, nframe = 10;</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; Source mySource = new Source();</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; ChannelMap cmap = new ChannelMap();</span><br style="font-family: monospace;">
<span style="font-family: monospace;"></span><span style="font-family: monospace;"></span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; for(int i
= 0; i &lt; nchan; ++i) cmap.Add("C"+i);</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mySource.OpenRBNBConnection("localhost",
"mySource");</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; for (int
j = 0; j &lt; nframe; ++j) {</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
for (int i = 0; i &lt; nchan; ++i)</span><span style="font-family: monospace;"> {</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
cmap.PutTime((double)i, 0.);</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
cmap.PutDataAsString(i, "Data for Channel C" + i);</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
mySource.Flush(cmap, true);</span><span style="font-family: monospace;"></span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
}&nbsp;&nbsp;&nbsp; </span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </span><span style="font-family: monospace;"></span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mySource.Detach(); &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;// data remains after Detach</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
}</span><br style="font-family: monospace;">
<span style="font-family: monospace;">}<br>
</span></td>
</tr>
</tbody>
<caption align="bottom"><b>Looping Source Example
Code</b></caption>
</table>
</center>
<br>
<hr width="100%">
<br>
<h2><a name="3.3 Sink Client"></a>3.3&nbsp;&nbsp;&nbsp;
Sink Client</h2>
An RBNB data sink fetches data from and RBNB server. A sink client has
the following tasks, repeated as desired:
<blockquote> <li> Specify request ChannelMap</li>
<li> Select sink mode</li>
<li> Fetch response ChannelMap</li>
<li> Extract data and time from response ChannelMap</li>
</blockquote>
<h3> <a name="3.3.1 Request ChannelMap"></a>3.3.1&nbsp;&nbsp;&nbsp;
Request ChannelMap</h3>
A Sink clients formulates a request ChannelMap that defines the names
and timestamps of the data to be fetched.&nbsp; Channel names are
defined
by calls to the <a href="#ChannelMap.Add">ChannelMap.Add</a>
method, and
the associated channel times are defined by calls to the <a href="#ChannelMap.PutTime">ChannelMap.PutTime</a>
method(s).
<h3> <a name="3.3.2 Sink Modes"></a>3.3.2&nbsp;&nbsp;&nbsp;
Sink Modes</h3>
There are three types of sink data fetch modes:
<ul>
<li> <tt>Subscribe - </tt>All new data is to be
streamed without gaps</li>
<li> <tt>Monitor&nbsp;&nbsp; - </tt>"Current"
up-to-date live information is to be sent best-effort.</li>
<li> <tt>Request&nbsp;&nbsp; - </tt>A
particular time-slice of data is requested</li>
</ul>
Each sink fetch mode applies to the group of channels specified by the
ChannelMap.
<h4> <a name="Sink.Subscribe"></a><tt>void
Subscribe(ChannelMap cmap)</tt></h4>
This is the simplest data fetch mode.&nbsp; It takes a channel map
as
an argument and returns no value.&nbsp; It initiates a streaming
"push"
of data (from server to client) for all specified channels starting at
the
time of this call, and proceeding into the future.&nbsp; A single
call to
Subscribe can be followed by repeated calls to Fetch, where the next
frame
of data is received.&nbsp; Note that the frame size is determined
by the
source application(s).
<p>Subscribe is the most efficient mode in that data frames are
streamed from
the server without waiting for acknowledgment from the sink
client.&nbsp; If the client does not keep up, the data delivered
will fall further and further behind until it falls off the beginning
(oldest) data in the source ring buffer, at which point the stream
aborts. </p>
<h4> <a name="Sink.Monitor"></a><tt>void
Monitor(ChannelMap cmap, int gapControl)</tt></h4>
This provides a variation on the subscribe mode.&nbsp; It initiates
a
stream of "current" data that will skip-forward as necessary to stay up
to date.&nbsp; Full source frames are returned each Fetch. The <tt>gapControl</tt>
argument specifies how many frames behind it can get before it will
jump
ahead (and miss data) in order to stay current.
<p>When Monitor mode keeps up, it is much like Subscribe, except
that there is more round-trip traffic between the client and server for
Monitor mode (to establish the <tt>gapControl</tt>
criterion).&nbsp; Unlike Subscribe mode, the stream will not abort
if the client doesn't keep up; but data can be dropped with resulting
gaps. </p>
<p><b><i>Note:</i></b>&nbsp; As of
the current release, the gapcontrol logic is (still) not fully
implemented. </p>
<h4> <a name="Sink.Request"></a><tt>void
Request(ChannelMap cmap, double
start, double duration, String timeRef)</tt></h4>
The basic Request mode asks for a time-slice of data beginning at <tt>start</tt>
and running for a <tt>duration</tt> amount.&nbsp; The <tt>timeRef</tt>
argument specifies the time-reference for <tt>start</tt>.&nbsp;
The following
table summarizes the most commonly used <span style="font-family: monospace;">timeRef</span>
options. &nbsp;See the Javadoc for a complete reference.<br>
&nbsp;
<center>
<table border="1" width="90%">
<tbody>
<tr>
<td><b>&nbsp;timeRef</b></td>
<td><b>&nbsp;Description</b></td>
</tr>
<tr>
<td>&nbsp;"absolute"&nbsp;</td>
<td>Request a <tt style="font-weight: bold;">duration</tt><span style="font-weight: bold;"> </span>amount of data
at a <tt style="font-weight: bold;">start</tt><span style="font-weight: bold;"> </span>time specified in
absolute-seconds
from midnight, Jan 1st, 1970 UTC.<br>
The data retrieved will be that which has <span style="font-weight: bold; font-family: monospace;">time</span>
in the interval:&nbsp; <span style="font-weight: bold; font-family: monospace;">start</span>
&lt;= <span style="font-weight: bold; font-family: monospace;">time</span>
&lt; (<span style="font-weight: bold; font-family: monospace;">start</span><span style="font-family: monospace;">+</span><span style="font-weight: bold; font-family: monospace;">duration</span>)</td>
</tr>
<tr>
<td>&nbsp;"oldest"</td>
<td>Request a <tt style="font-weight: bold;">duration</tt><span style="font-weight: bold;"> </span>amount of data
where <tt style="font-weight: bold;">start</tt><span style="font-weight: bold;"> </span>is relative to the
oldest&nbsp;available
data (beginning of ring-buffer). <br>
With a zero <span style="font-weight: bold; font-family: monospace;">start</span>-time,
it retrieves the oldest <span style="font-family: monospace; font-weight: bold;">duration</span>
of data. &nbsp;In general, the data retrieved will be that which
has <span style="font-weight: bold; font-family: monospace;">time</span>
in the interval: &nbsp;(<span style="font-family: monospace;">oldest</span>+<span style="font-weight: bold; font-family: monospace;">start</span>)
&lt;= <span style="font-weight: bold; font-family: monospace;">time</span><span style="font-family: monospace;"> </span>&lt; (<span style="font-family: monospace;">oldest</span> + <span style="font-weight: bold; font-family: monospace;">start</span>
+ <span style="font-weight: bold; font-family: monospace;">duration)
</span></td>
</tr>
<tr>
<td valign="top">"newest"<br>
</td>
<td valign="top">Request a <tt style="font-weight: bold;">duration</tt><span style="font-weight: bold;">
</span>amount of most recent
data (end of ring-buffer).&nbsp; With a zero <span style="font-weight: bold; font-family: monospace;">start</span>-time,
it retrieves the newest <span style="font-family: monospace; font-weight: bold;">duration</span>
of data. &nbsp;In general, the data retrieved will be that which
has <span style="font-weight: bold; font-family: monospace;">time</span>
in the interval: &nbsp;(<span style="font-family: monospace;">newest</span>-<span style="font-weight: bold; font-family: monospace;">duration</span>-<span style="font-weight: bold; font-family: monospace;">start</span>)
&lt; <span style="font-weight: bold; font-family: monospace;">time</span><span style="font-family: monospace;"> </span>&lt;= <span style="font-family: monospace;">(newest-<span style="font-weight: bold; font-family: monospace;">start</span>)</span><span style="font-weight: bold; font-family: monospace;"></span><br>
</td>
</tr>
</tbody>
</table>
</center>
<br>Additional <span style="font-family: monospace;">timeRef</span>
options include "aligned", "after", "modified", "next", "previous".
&nbsp;These enable sequences of relative requests moving back and
forth
in time&nbsp; without overlapping data. &nbsp; Refer to the
SAPI
Javadoc for detailed description of these advanced options.<br><br>Note that both <span style="font-family: monospace;">start</span>
and <span style="font-family: monospace;">duration</span>
are always positive numbers.
&nbsp;For "absolute" and "oldest" time-references, <span style="font-family: monospace;">duration</span>
extends to right (future)
of the <span style="font-family: monospace;">start</span>
point. &nbsp;For
all the other (e.g. "newest") time-references, <span style="font-family: monospace;">duration </span>extends
to the left (prior)
of the <span style="font-family: monospace;">start</span>
point. For example, to get the most recent&nbsp;data, use a <span style="font-family: monospace;">start</span> of zero: <tt><br>
<br>
</tt>
<div style="margin-left: 40px;"><tt>sink.Request(cmap,
0, 1, "newest")</tt><br>
</div>
<p>There is always one <tt>Fetch'</tt>d channel map
returned for each <tt>Request</tt>, even if this is a <i>NULL</i>
map for the cases where there is no data. A
<span style="font-style: italic;">NULL</span> map
can occur for the "after"
or "modified" cases, or when there is simply no data at the requested
time.</p>
<p>A <span style="font-family: monospace;">duration</span>
of zero (0.) is a special case. &nbsp;It retrieves a single point
(frame) of data at-or-before the specified <span style="font-family: monospace;">time</span>.
&nbsp;Note that a non-zero <span style="font-family: monospace;">duration</span>
can specify an interval that is in-between other data, thus returning
an empty ChannelMap.</p>

<h4> <a name="Sink.RequestRegistration"></a><tt>void
RequestRegistration(ChannelMap cmap)</tt></h4>
Sends a request to the server for the current registration map for the
channels in the specified cmap.&nbsp; The channel map retrieved via
the followup <span style="font-family: monospace;">Fetch</span>
call can be inspected
using the&nbsp;<a href="#GetChannelList">GetChannelList</a>
method to get a list of channels and other server objects (sources,
sinks). The Registration channel map will contain any source-provided
metadata.&nbsp;
<h3> <a name="3.3.3 Fetch Data"></a>3.3.3&nbsp;&nbsp;&nbsp;
Fetch Response</h3>
After building the ChannelMap and setting the <a href="#3.3.2%20Sink%20Modes">Sink Mode</a> (in that
order), get the RBNB data using the Fetch method.
<h4> <a name="Sink.Fetch"></a><tt>ChannelMap
Fetch(boolean blockingIO)</tt></h4>
This method reads the data from the RBNB server for all channels in the
current local Channel List (built by <a href="#ChannelMap.Add">ChannelMap.Add</a>).&nbsp;
It returns the number of channels retrieved.
<p>If the <tt>blockingIO</tt> parameter is <tt>true</tt>,
it will block until the data is retrieved.&nbsp; Otherwise, it will
either return a positive integer indicating data was ready and has been
read, or a zero (0) indicating no data was yet available. </p>
<h3> <a name="3.3.4 Extract Data"></a>3.3.4&nbsp;&nbsp;&nbsp;
Extract Data</h3>
Fetched data is stored the ChannelMap returned by Fetch.&nbsp;
Access
to the data and time is via the associated <a href="#2.4.2%20Getting%20Data">ChannelMap.Get</a>
methods.
<h3> <a name="3.3.5 Example Sink Code"></a>3.3.5
Sink Example Code</h3>
The following code will fetch the message sent to the local
RBNB Server by the earlier <a href="#3.2.5%20Example%20Source%20Code">Data-Source</a>
example. <br>
&nbsp;
<center>
<table border="1" cols="1" width="95%">
<tbody>
<tr>
<td> <span style="font-family: monospace;">//
RBNB Developer Guide Simple Sink Example</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">import
com.rbnb.sapi.*;</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">class
simpleSink</span><br style="font-family: monospace;">
<span style="font-family: monospace;">{</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
public static void main(String[] arg) throws Exception</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
{</span><span style="font-family: monospace;"></span><span style="font-family: monospace;"></span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; Sink mySink = new Sink();</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mySink.OpenRBNBConnection("localhost", "mySink");</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; ChannelMap reqmap = new ChannelMap();</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
reqmap.Add("mySource/myChan");</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mySink.Request(reqmap, 0., 0., "newest");&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; // get most recent data</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; ChannelMap getmap = mySink.Fetch(1000);</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; System.out.println(getmap.GetName(0)+": "+getmap.GetDataAsString(0)[0]);</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; mySink.CloseRBNBConnection();</span><span style="font-family: monospace;"></span><span style="font-family: monospace;"></span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
}</span><br style="font-family: monospace;">
<span style="font-family: monospace;">}</span>
</td>
</tr>
</tbody><caption align="bottom"><b>Sink
Example Code</b></caption>
</table>
</center>
<h2>
<hr width="100%"></h2>
<h2> <a name="3.4 PlugIn Client"></a>3.4&nbsp;&nbsp;&nbsp;
PlugIn Client</h2>
An RBNB PlugIn is a special client that connects as a combination
source/sink. When a third-party sink requests a channel from the
PlugIn, this request (via a ChannelMap object) is sent from the RBNB
server to that PlugIn. The PlugIn fills in the answer (puts data) into
this request map and returns it,
thus dynamically responding to data requests.
<p>A PlugIn client shares the <a href="#Sink.Fetch">Fetch</a>
and <a href="#Source.Flush">Flush</a> methods from
the Sink and Source classes, respectively. </p>
<h4> <a name="PlugIn.Register"></a><b><tt>void
PlugIn.Register(ChannelMap cmap)</tt></b></h4>
A PlugIn may (optionally) register the channels that it can
provide.&nbsp;
These channels become part of the ChannelList for the PlugIn, i.e. they
are a means of "advertising" available channels..&nbsp; Data
contained in
Registered channels are considered metadata.
<p>If <i>any</i> channels are registered by a
PlugIn, <i>only</i> requests for those specific channels
will be forwarded by the server to that PlugIn.&nbsp; If <i>no</i>
channels are registered by a PlugIn, then <i>any</i>
requests to that PlugIn (e.g. "Plugin/anychan") will be forwarded to
the PlugIn, that
must look at the channel name(s)&nbsp; and decided what to do. </p>
<h3> <a name="3.4.1 PlugIn ChannelMap"></a>3.4.1&nbsp;&nbsp;&nbsp;
PlugInChannelMap</h3>
A PlugInChannelMap is a dual-purpose object. It is fetched to determine
a request, and filled in with data to be returned as a
response.&nbsp; It is required that the response ChannelMap is the
same object as the fetched (request) ChannelMap, as this ties the
response to the request.
<p>PlugIns extend regular ChannelMaps to add a few methods unique
to their needs. </p>
<h4> <tt>double GetRequestStart()</tt></h4>
<h4> <tt>double GetRequestDuration()</tt></h4>
The request start and duration indicate the time-slice to be
processed.&nbsp; By default, these values constitute the
start/duration of the response.&nbsp; That is, there is no need to
call <a href="#ChannelMap.PutTime">PutTime</a> on
the response map unless the response map time is different than the
request map.
<h4> <tt>String GetRequestReference()</tt></h4>
This method returns the type of request being made. The following
correspond to the timeRef argument of the corresponding <a href="#Sink.Request">Sink.Request</a> call:
<blockquote><tt>"newest", "oldest", "absolute", "modified",
"after"</tt></blockquote>
The following correspond to <a href="#Sink.Subscribe">Sink.Subscribe</a>
and <a href="#Sink.Monitor">Sink.Monitor</a> data
requests, respectively:
<blockquote><tt>"subscribe", "monitor"</tt></blockquote>
<b><i>Note:</i></b>&nbsp;&nbsp;
"subscribe" and "monitor" modes are not supported for PlugIns, but are
implemented for <a href="#3.4.3_Plugin_Template">Plugin
Templates</a>.<br>
&nbsp;
<h3> <a name="3.3.5 Example Sink Code"></a>3.4.2
PlugIn Example Code</h3>
The following PlugIn code echos the name of the requested channel in
response
to any request. <br>
&nbsp;
<center style="font-family: monospace;">
<table border="1" cols="1" width="95%">
<tbody>
<tr>
<td> // RBNB Developer Guide Simple PlugIn Example<br>
<br>
import com.rbnb.sapi.*;<br>
<br>
class simplePlugIn<br>
{<br>
&nbsp;&nbsp;&nbsp; public static void main(String[] arg)
throws Exception<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PlugIn
myPlugIn = new PlugIn();<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
myPlugIn.OpenRBNBConnection("localhost", "myPlugIn");<br>
<br>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; while(true)
{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // run
until killed<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; PlugInChannelMap cmap =
myPlugIn.Fetch(1000);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt;
cmap.NumberOfChannels(); i++) {<br>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; String
response = new String("Got request for: "+cmap.GetName(i));<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
cmap.PutDataAsString(i, response);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; }<br>
<br>
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
myPlugIn.Flush(cmap); <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
}&nbsp;</td>
</tr>
</tbody><caption align="bottom"><b>PlugIn
Example Code</b></caption>
</table>
</center>
<h3><a name="3.4.3_Plugin_Template"></a> 3.4.3
Plugin Template</h3>
The
PlugInTemplate class is an abstract base class that simplifies PlugIn
development. &nbsp;It automatically provides data-streaming (i.e.
subscribe and monitor) support by converting such streams to a sequence
of requests that the plugin template developer can handle one-by-one.<br>
<h4><tt><tt>void processRequest(ChannelMap fwdData,
PlugInChannelMap out)</tt></tt></h4>
Most plugin implemenations will only need to overload this method in
order to have a fully functional plugin. &nbsp;<br>
<br>
When
a sink requests data from this plugin with follow-on reference to other
RBNB data, this data is automatically provided via the <span style="font-weight: bold;">fwdData</span> parameter.
&nbsp;The method returns its results via the <span style="font-weight: bold;">out</span> parameter.
The following simple example echoes the name of
the&nbsp;requested channel.<br>
<br>
<table style="width: 95%; text-align: left; margin-left: auto; margin-right: auto;" border="1" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td><span style="font-family: monospace;">//
RBNB Developer Guide Simple PlugIn Template Example</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">import
com.rbnb.sapi.*;</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">class
simplePlugInTemplate extends com.rbnb.plugins.PlugInTemplate</span><br style="font-family: monospace;">
<span style="font-family: monospace;">{</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
public simplePlugInTemplate()</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
{}</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
protected void processRequest<br>&nbsp; &nbsp; &nbsp; &nbsp; (ChannelMap fwdData, PlugInChannelMap
picm) throws SAPIException</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
{</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
// only process first channel</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; picm.PutDataAsString(0, "Got request to
process: "+fwdData.GetName(0));</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; return;</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
}</span><br style="font-family: monospace;">
<br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
public static void main(String[] arg)&nbsp;throws Exception</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
{</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; simplePlugInTemplate myPlugInTemplate =
new simplePlugInTemplate();</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; myPlugInTemplate.start();</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
}</span><br style="font-family: monospace;">
<span style="font-family: monospace;">}</span></td>
</tr>
</tbody>
</table>
<div style="text-align: center;"><span style="font-weight: bold;">PlugIn Template Example Code</span></div>
<br>
<hr width="100%">
<h1><a name="4_Routing_and_Mirrors"></a>4
Routing and Mirrors</h1>
<p class="MsoPlainText">RBNB servers can communicate with
each other
directly to form connected networks of servers. &nbsp;The two main
forms of inter-RBNB communication are Routing and Mirrors.</p>
<h2><a name="4.1_Mirrors_"></a>4.1 Mirrors<br>
</h2>
<p class="MsoPlainText">Mirrors "push" data from one data Source to
destination, making a copy of the Source on another RBNB server.<span style="">&nbsp; </span>Thus
with a mirror, a copy
of the data is automatically sent from the origin-source to the destination-mirror as it arrives.</p>
<p class="MsoPlainText">There are a two kinds of mirrors:<span style="">&nbsp; </span>a "From" mirror and a
"To" mirror. The difference is the side from which the connection is
established; after which the data is pushed from source to sink the
same as any
other mirror.</p>
<h2><a name="4.2_Routing"></a>4.2 Routing</h2>Whereas Mirrors connect one Source to another, Routes connect entire servers. &nbsp;Routes or routing "pull" data.<span style="">&nbsp; </span>Thus
with a route, only the registration
(channel metadata) is supplied a priori from source to sink; the data
is
fetched (over and over again) on-demand.
<p class="MsoPlainText">There are various forms of routing.<span style="">&nbsp; </span>Two types of routing are
built into the RBNB
server:<span style="">&nbsp; </span>parent/child
and shortcuts.<span style="">&nbsp;</span></p>
<p style="text-align: center;" class="MsoPlainText"><img style="width: 359px; height: 264px;" alt="RBNB Routes" src="RBNB_Routes.png"><br>
</p>
<p style="text-align: center; font-weight: bold;" class="MsoPlainText">RBNB Routing: &nbsp;Parent/Child
and Shortcuts</p>
<h3>4.2.1 Parent/Child Routes</h3>
<p class="MsoPlainText">Parent/child routes RBNB form a
rigid hierarchy with only
one "top" parent RBNB.<span style="">&nbsp; </span>An
RBNB server has only one opportunity to establish its parent server at
startup.<span style="">&nbsp; </span>Parent/child
routes are always
bidirectional; i.e. a parent can see and fetch data from its children
and
grandchildren, and a child can see and fetch data from its (single)
parent, grandparents,
cousins, etc.</p>
<h3>4.2.2 Shortcuts</h3>
<p class="MsoPlainText">Shortcuts are on-the-fly routes
that can be established
(and terminated) after RBNB servers are running.<span style="">&nbsp;
</span>They behave and function much like
parent/child routes after they are established, i.e. data is pulled
on-demand
across them.<span style="">&nbsp; </span>Shortcuts
form no rigid
hierarchy - this makes them flexible but lack the simple rules that
parent/child routes can use to find data.<span style="">&nbsp;
</span>Shortcuts are also inherently one-way connections.</p>
<h3>4.2.3 Routing via Plugins</h3>
<p class="MsoPlainText">Finally, it is possible to
implement routes (and to a
lesser extent mirrors) via clients such as plugins.<span style="">&nbsp;&nbsp;</span>The
"robust routing plugin" provided with the RBNB distribution is just one implementation of a routing plugin that tries
to be
more robust in that it will carefully watch for network disconnects and
automatically try to reconnect.</p>
<hr width="100%">
<h1><span style="font-weight: bold;"></span><a name="5_Web_Turbine"></a>5 &nbsp;WebTurbine
&nbsp; </h1>
<h2><a name="5.1_WebTurbine_Introduction"></a>5.1
&nbsp;WebTurbine Introduction</h2>
The WebTurbine interface is tied to the Apache Tomcat web server.
&nbsp;It provides a layer that makes an RBNB server appear to be an
HTTP web server. &nbsp;There exists URL syntax for putting and
getting
RBNB channels (one at a time).
<h3><span style=""><span style="">5.1.1<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>WebDAV</h3>
WebDAV is an extension to the ubiquitous HTTP protocol.<span style="">&nbsp;
</span>WebDAV stands for &#8220;Web Document Authoring and
Versioning.&#8221; With traditional HTTP, a Web server is a read-only device.<span style="">&nbsp; </span>WebDAV adds protocol
commands enabling a
client to write content to a Web server, with mechanisms to lock files
while
they are being accessed/edited. <span style="">&nbsp;</span>With
this write-capability, a WebDAV server becomes a full-featured network
file
server.<span style="">&nbsp; </span>Its
advantage versus other
approaches is its use of the existing Web infrastructure and the widely
supported HTTP protocol.<span style="">&nbsp; </span>
<h3><span style=""><span style="">5.1.2<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>WebDAV
Enabled RBNB</h3>
The RBNB &#8220;WebTurbine&#8221; adds a web-server layer between the
RBNB server and client applications.<span style="">&nbsp;
</span>Specifically, it is a &#8220;servlet&#8221; that runs under the Apache
Tomcat web
server.<span style="">&nbsp; <br>
<br>
</span>The popular open-source Apache Tomcat (Java) Web server
includes a fully featured WebDAV interface that connects to
an RBNB server instead of the traditional local file-set.<span style="">&nbsp;</span><span style=""></span>RBNB
data channels can be HTTP URLs and network-mounted WebDAV
&#8220;files&#8221;.<span style="">&nbsp; </span>Each
root-level directory is an RBNB data
source, and each &#8220;file&#8221; below this source is an RBNB channel.<span style="">&nbsp; </span>This provides a web URL
and file-folder
interface to the entire contents of the RBNB.<span style="">&nbsp;
</span>
<h3><span style=""><span style="">5.1.3<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>URL
Syntax</h3>
In the tradition of the Web, from a browser or other HTTP
application, access to RBNB data channels is via&nbsp;URL of the
form:
<p class="MsoNormal" style="margin-bottom: 12pt; text-align: center;" align="center"><span style="font-family: monospace;">http://rbnb-host:port/RBNB/rbnb-server/source/channel</span><span style="font-family: Courier;"><o:p></o:p></span></p>
<p class="Paragraph"><span style="color: black;">Seen
as Web objects or files, URLs
to RBNB data channels by default reference the most-recent data point
of a
streaming time-sequence. </span>A &#8220;point&#8221; is an indivisible data
word.<span style="">&nbsp; </span>For example,
it may be an image, a file, or
one floating point number from a signal stream.<span style="">&nbsp;
</span>To specify a range of data points over a time interval,
you can use a
URL &#8220;munge&#8221; syntax as follows:<span style="color: black;"><o:p></o:p></span></p>
<ul>
<li><span style="font-size: 10pt; font-family: Courier; color: black;"><span style=""></span>mydata?d=10<o:p></o:p></span></li>
<li><span style="font-size: 10pt; font-family: Courier; color: black;"><span style=""></span>video.jpg?t=360&amp;d=0.2<o:p></o:p></span></li>
<li><span style="font-size: 10pt; font-family: Courier; color: black;"><span style=""></span>chatmsg?t=600&amp;r=newest<o:p></o:p></span></li>
</ul>
<p class="Paragraph"><o:p></o:p><span style="color: black;">In the above examples, <b style="">&#8220;t&#8221;</b>
</span>refers to time-stamp, <b style="">&#8220;d&#8221;</b>
to duration of the time-slice, and <b style="">&#8220;r&#8221;</b>
is an optional reference to <i style="">oldest<span style="color: black;"> </span></i><span style="color: black;">or </span><i style="">newest</i><span style="color: black;"> time (versus </span><i style="">absolute</i><span style="color: black;">).<span style="">&nbsp; </span>Concatenate
multiple references with the <b style="">&#8220;&amp;&#8221; </b>symbol.<o:p></o:p></span></p>
<p class="Paragraph">Note that although URLs are typically
used to get or read
data, it is also possible to PUT or POST content to a web server via
URL.<span style="">&nbsp; </span>The RBNB web
interface is fully
bi-directional.<span style="">&nbsp; </span>Munging
the timestamp on
a write specifies the time of the data being written.<span style="">&nbsp;
</span>By default, data writes are automatically
time-stamped with current time-of-day.</p>
<p class="Paragraph">A complete reference to the WebDAV
options is bundled with the RBNB DataTurbine software release.</p>
<h3><span style=""><span style="">5.1.4<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>Interface
Options</h3>
There are several ways in which applications can access the
WebDAV-enabled WebTurbine system:
<ul style="margin-left: 40px;">
<li><span style="font-family: Symbol;"><span style=""><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span></span>Web
URL</li>
<li><span style="font-family: Symbol;"><span style=""><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span></span>File
System</li>
<li><span style="font-family: Symbol;"><span style=""></span></span>Programmer</li>
</ul>
<p class="Paragraph">Each of these goes through the
rbnbDAV server, using the
HTTP/WebDAV protocol. These are each described in turn in the following
sections.</p>
<h2><span style=""><span style=""><a name="5.2_Web_URL_Access"></a>5.2<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp; </span></span></span>Web URL Access</h2>
<p>Launched as a Web server &#8220;servlet,&#8221; all RBNB content may be
accessed via URL references<span style="color: black;">.<span style="">&nbsp; </span></span>For example,
through a link such as <u><span style="color: maroon;">http://localhost/RBNB</span></u>,
you may peruse
live current content via your browser or any other application that can
open
Web URLs. </p>
<p class="MsoNormal" style="text-align: center;" align="center"><o:p><img style="width: 605px; height: 507px;" alt="Web Browser Interface" src="WebBrower.jpg">&nbsp;</o:p></p>
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-weight: bold;">&nbsp;WebTurbine
Browser Interface</span></p>
<p class="Paragraph"><span style="color: black;">The
RBNB Web interface operates as
a WebDAV server, so you can even <i style="">write</i>
content to the RBNB using this means.<span style="">&nbsp;
</span>Many applications (such as Microsoft Office) are &#8220;WebDAV
enabled,&#8221; and
it is easy to write custom applications that use this bidirectional
read/write
interface.<o:p></o:p></span></p>
<p class="Paragraph"><span style="color: black;">Once
you have launched the
WebTurbine and RBNB servers, you can point your browser at the
WebTurbine
servlet-root at &#8220;/RBNB&#8221; below your Web server home URL.<span style="">&nbsp;
</span>For example, if you are running the Tomcat
web server at </span><span style="font-size: 11pt; font-family: Courier; color: black;">localhost:8080</span><span style="color: black;">,
and an RBNB server with name </span><span style="font-size: 11pt; font-family: Courier; color: black;">Server</span><span style="color: black;">,
the URL to the root directory to the RBNB data channels would be:<o:p></o:p></span></p>
<div style="text-align: center;"><span style="font-size: 11pt; color: black; font-family: monospace;">http://localhost:8080/RBNB</span><span style="font-size: 11pt; font-family: Courier;"><o:p></o:p></span></div>
<p class="Paragraph">Below this point appears what looks
like a file system
consisting of the various RBNB data sources and channels.<span style="">&nbsp; </span>If you have routed RBNB
servers together, you
can continue down this hierarchy to access content from remotely routed
RBNBs.</p>
<h2><span style=""><span style=""><a name="5.3_File_System_Access"></a>5.3<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>File
System Access<span style="color: black;"></span></h2>
<p><span style="color: black;">RBNB file system
mapping is
accomplished via built-in WebDAV support in Windows XP, Mac OS X,
Mandrake
Linux, and several other systems and </span>third<span style="color: black;">
party packages.<span style="">&nbsp; </span>Many
WebDAV file system
clients provide full access to any application that can read and write
files.<o:p></o:p></span></p>
<h3><span style=""><span style="">5.3.1<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>File
Explorer Interface</h3>
<p class="Paragraph"><span style="color: black;">The
RBNB server can be mapped as a
network drive, giving you a familiar file-folder interface to RBNB
dynamic data
files.<span style="">&nbsp; </span>An easy way
to do this is as a
WebFolder via Microsoft Internet Explorer.<span style="">&nbsp;
</span>Simply <b style=""><i style="">Open...</i></b>
under the IE <b style=""><i style="">File</i></b>
menu, enter the RBNB server
site (e.g.,&nbsp;</span><u><span style="color: maroon;">http://localhost/RBNB</span></u><span style="color: black;">), and check the <b style=""><i style="">Open as WebFolder</i></b> box.<span style="">&nbsp; </span>The resulting folder
window lets you browse
and read content across a network of routed RBNB servers.</span></p>
<p style="text-align: center;" class="Paragraph"><span style="color: black;"><img style="width: 668px; height: 355px;" alt="File Explorer Interface" src="FileExplorer.jpg"></span></p>
<p class="MsoNormal" style="text-align: center;" align="center"><o:p style="font-weight: bold;"></o:p><span style="font-weight: bold;"> WebTurbine File Explorer
Interface</span></p><p class="MsoNormal" style="text-align: left;">Windows
also (sometimes) works using the "Map Network Drive" feature pointing
to the WebTurbine servlet URL, e.g. http://localhost/RBNB. &nbsp; Other
operating systems also provide WebDAV file-system support. &nbsp;On the
Mac OS X, use the top-panel Go/Connect to Server interface. &nbsp;On
Linux, use the "dav2fs" utility.<span style="font-weight: bold;"></span></p>
<h3><span style=""><span style="">5.3.2<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>Shell
Interface</h3>
<p class="Paragraph">This syntax can be used by shell
commands, as part of Web
URLs, and in any programming language that supports simple file I/O.<span style="">&nbsp; </span>The following illustrates
RBNB dynamic file
access via Unix shell commands:</p>
<div style="margin-left: 40px;"><span style="font-size: 10pt; font-family: monospace;">$ cd
/mnt/RBNB/rbnbSource<span style="">&nbsp;&nbsp;&nbsp;&nbsp;
</span>&nbsp; %
change to rbnbDAV source folder<o:p></o:p></span><span style="font-family: monospace;">
</span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;">$
cp c0 /usr/mjm/mycopy<span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>&nbsp; %
grab most recent data (default)<o:p></o:p></span><span style="font-family: monospace;">
</span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;">$
cat c0@t=4&amp;d=1<span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>&nbsp; %
type data at time=4, duration=1<o:p></o:p></span><span style="font-family: monospace;">
</span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><o:p>&nbsp;</o:p></span><span style="font-family: monospace;">
</span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;">$
cd /mnt/RBNB<span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>&nbsp; %
change to rbnbDAV server root folder<o:p></o:p></span><span style="font-family: monospace;">
</span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;">$
mkdir myStuff<span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>&nbsp; %
create a new RBNB source (RBO)<o:p></o:p></span><span style="font-family: monospace;">
</span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;">$
cp /usr/mjm/foo myStuff<span style="">&nbsp;&nbsp;&nbsp;&nbsp;
</span>&nbsp; %
put data channel &#8220;foo&#8221; (at default TOD)<o:p></o:p></span><span style="font-family: monospace;">
</span><br style="font-family: monospace;">
<span style="font-size: 10pt;"><span style="font-family: monospace;">$ echo &#8220;hi&#8221; &gt;
myStuff/c0@t=47 &nbsp; % put message in at time=47</span></span><span style="font-size: 10pt; font-family: Courier;"><o:p></o:p></span><span style="font-size: 10pt; font-family: Courier;"><o:p>&nbsp;</o:p></span></div>
<p class="Paragraph">Equivalent functions are available
from other operating
systems, such as the Windows command prompt.&nbsp;</p><p class="Paragraph">Note that the '@' symbol is an optional substitute for the '?' munge character; this helps when '?' is a shell wildcard.</p>
<h3><span style=""><span style="">5.3.3<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>File
I/O Interface </h3>
<p class="Paragraph">Any software program can access RBNB
data as if it were a
file.<span style="">&nbsp; </span>The following
&#8220;C&#8221; code is a simple
example of an RBNB data source.<span style="">&nbsp; </span>Note
that no RBNB-specific API or libraries are used.<span style="">&nbsp;
</span>All that is necessary is for the &#8220;rbnbDAV&#8221;
server to be mounted as a local file system using standard OS-vendor
utilities
or open-source libraries.</p>
<table class="MsoNormalTable" style="border: medium none ; margin-left: 41.4pt; border-collapse: collapse; width: 680px; height: 210px;" border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr style="page-break-inside: avoid;">
<td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 5.75in;" valign="top" width="552"> <span style="font-size: 10pt; font-family: monospace;">// Simple
&#8220;C&#8221; Example of RBNB Data Source using rbnbDAV<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><o:p>&nbsp;</o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;">#include
&lt;stdio.h&gt;<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><o:p>&nbsp;</o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;">main()<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;">{<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><span style="">&nbsp; </span>char dbuf[256];<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><span style="">&nbsp; </span>FILE *fp =
fopen(&#8220;myChan@t=3&#8221;,&#8220;w&#8221;); <span style="">&nbsp;&nbsp;&nbsp;
</span>// open channel<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><o:p>&nbsp;</o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><span style="">&nbsp; </span>printf(&#8220;Enter:&#8221;);<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><span style="">&nbsp; </span>fgets(dbuf, 256, stdin);<span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><span style="">&nbsp;&nbsp;&nbsp;&nbsp;
</span>// get user message<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><span style="">&nbsp; </span>fwrite(dbuf, 1,
strlen(dbuf), fp); <span style="">&nbsp;&nbsp;&nbsp;&nbsp;
</span>// write it to RBNB<o:p></o:p></span><span style="font-family: monospace;"> </span><br style="font-family: monospace;">
<span style="font-size: 10pt; font-family: monospace;"><span style=""></span>}</span><span style="font-family: Courier;"><o:p></o:p></span>
</td>
</tr>
</tbody>
</table>
<p class="Paragraph" style="margin-top: 12pt;">An
RBNB data sink to read this
source (located far away across a network of servers) could simply open
this
same &#8220;file&#8221; for read access.</p>
<h2><span style=""><span style=""><a name="5.4_Programmer_Interface"></a>5.4<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></span>Programmer
Interface</h2>
<p>It is possible to write programs which open,
read, and write via HTTP connections. &nbsp;With this
approach,&nbsp; it is possible to use the Web interface
in lieu of the standard RBNB Java API libraries for programmatic access
to RBNB
data.<span style="">&nbsp; </span>This has
several advantages:</p>
<ul style="margin-left: 40px;">
<li><span style="font-family: Symbol;"><span style=""><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span></span>It
requires no special RBNB libraries or code at
the client side</li>
<li><span style="font-family: Symbol;"><span style=""></span></span>It
is arguably simpler than the standard RBNB
Java API</li>
<li><span style="font-family: Symbol;"><span style=""><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span></span>It
is portable to programming languages other
than Java</li>
</ul>
<p class="Paragraph">For the Java programmer, this
approach has the
disadvantages:</p>
<ul style="margin-left: 40px;">
<li><span style="font-family: Symbol;"><span style=""></span></span>Somewhat
restricted supported features (e.g. no
subscribe-mode, one channel at a time)</li>
<li><span style="font-family: Symbol;"><span style=""><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span></span>It
requires a WebTurbine/WebDAV server to be
running</li>
<li><span style="font-family: Symbol;"><span style=""><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"></span></span></span>Performance
is less optimal due to the
additional data-hop and software layer</li>
</ul>
<p>The syntax for how to program HTTP I/O is beyond the scope of
this document.</p><p></p><h3><span style=""><span style=""></span></span></h3>
<p class="MsoPlainText" style="margin: 0in -9pt 0.0001pt;"><o:p>&nbsp;</o:p></p>
<p class="Paragraph" style="text-indent: 0in;"><o:p>&nbsp;</o:p></p>
<br>
<br>
<br>
<br>
</body></html>